package com.bestcem.xm.ticket.service.impl;

import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.ticket.controller.convert.TicketVOConvert;
import com.bestcem.xm.ticket.controller.v2.param.WeChatTicketSearchParam;
import com.bestcem.xm.ticket.controller.vo.ticket.TicketPageVO;
import com.bestcem.xm.ticket.dao.TicketConfigDao;
import com.bestcem.xm.ticket.dao.TicketDao;
import com.bestcem.xm.ticket.dao.dto.TicketInfo;
import com.bestcem.xm.ticket.entity.mongo.Ticket;
import com.bestcem.xm.ticket.entity.mongo.TicketConfig;
import com.bestcem.xm.ticket.enums.TicketStatusEnum;
import com.bestcem.xm.ticket.grpc.client.TicketBaseQdesGrpcService;
import com.bestcem.xm.ticket.grpc.client.TicketBaseUserGrpcService;
import com.bestcem.xm.ticket.grpc.client.dto.qdes.QdesDTO;
import com.bestcem.xm.ticket.grpc.client.dto.user.UserDTO;
import com.bestcem.xm.ticket.service.TicketService;
import com.bestcem.xm.ticket.service.WechatWorkService;
import com.bestcem.xm.ticket.service.convert.TicketInfoConvert;
import com.bestcem.xm.ticket.service.dto.PageDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.bestcem.xm.common.core.uitls.DateUtil.BEIJING_ZONE;
import static com.bestcem.xm.common.core.uitls.DateUtil.UTC_ZONE;

/**
 * 企业微信小程序定制接口 实现
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.com>
 * @version WechatWork
 * @date 2021/12/17 15:29
 */
@Slf4j
@Service
public class WechatWorkServiceImpl implements WechatWorkService {

    @Resource
    private TicketService ticketService;

    @Resource
    private TicketDao ticketDao;
    @Resource
    private TicketConfigDao ticketConfigDao;

    @Resource
    private TicketBaseUserGrpcService ticketBaseUserGrpcService;
    @Resource
    private TicketBaseQdesGrpcService ticketBaseQdesGrpcService;


    /**
     * 企业微信小程序定制版 工单分页搜索接口
     *
     * @param param 分页搜索参数
     * @return 分页搜索结果
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/12/17 15:31
     */
    @Override
    public ServiceResult<PageDTO<TicketPageVO>> searchTicket(WeChatTicketSearchParam param) {
        PageDTO<Ticket> ticketPageDTO = ticketDao.wechatPageTicket(param);
        PageDTO<TicketPageVO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(ticketPageDTO.getTotal());
        pageDTO.setPage(param.getPage() + 1);

        List<Ticket> ticketList = ticketPageDTO.getData();
        List<TicketPageVO> ticketPageVOS = new ArrayList<>();
        if (CollectionUtils.isEmpty(ticketList)) {
            pageDTO.setData(ticketPageVOS);
            return ServiceResult.success(pageDTO);
        }

        Set<String> ticketConfigIds = new HashSet<>();
        Set<String> userIds = new HashSet<>();
        Set<String> surveyIds = new HashSet<>();
        for (Ticket ticket : ticketList) {
            if (!ObjectUtils.isEmpty(ticket.getTicketConfigId())) {
                ticketConfigIds.add(ticket.getTicketConfigId());
            }
            if (!ObjectUtils.isEmpty(ticket.getCreatedId())) {
                userIds.add(ticket.getCreatedId());
            }
            if (!ObjectUtils.isEmpty(ticket.getSurveyId())) {
                surveyIds.add(ticket.getSurveyId());
            }
        }
        // 查出这一批工单对应的工单配置 做缓存
        Map<String, TicketPageVO.AlertRule> alertCache = new HashMap<>();
        List<TicketConfig> ticketConfigs = ticketConfigDao.listByIds(ticketConfigIds);
        if (!CollectionUtils.isEmpty(ticketConfigs)) {
            for (TicketConfig ticketConfig : ticketConfigs) {
                alertCache.put(ticketConfig.getId(),
                        new TicketPageVO.AlertRule(ticketConfig.getTitle(), ticketConfig.getId()));
            }
        }
        // 查出这一批工单对应的创建人 做缓存
        Map<String, String> usernameCache = new HashMap<>();
        List<UserDTO> userDTOs = ticketBaseUserGrpcService.listUserByIds(userIds);
        if (!CollectionUtils.isEmpty(userDTOs)) {
            for (UserDTO userDTO : userDTOs) {
                usernameCache.put(userDTO.getId(), userDTO.getName());
            }
        }
        // 查出这一批工单对应的问卷 做缓存
        Map<String, String> surveyTitleCache = new HashMap<>();
        List<QdesDTO> qdesDTOS = ticketBaseQdesGrpcService.listQdesProjectByIds(surveyIds);
        if (!CollectionUtils.isEmpty(qdesDTOS)) {
            for (QdesDTO qdesDTO : qdesDTOS) {
                surveyTitleCache.put(qdesDTO.getId(), qdesDTO.getTitle());
            }
        }

        for (Ticket ticket : ticketList) {

            TicketPageVO ticketPageVO = TicketVOConvert.entityToTicketPageVO(ticket);
            ticketPageVO.setTicketDeadline(null);

            // 创建人; 若没有创建人 则默认为 系统
            String username = usernameCache.get(ticket.getCreatedId());
            if (ObjectUtils.isEmpty(username)) {
                username = "系统";
            }
            ticketPageVO.setCreatedName(username);

            // 问卷项目的最新标题; 若没有标题 则使用工单创建时存的问卷项目标题
            String surveyTitle = surveyTitleCache.get(ticket.getSurveyId());
            if (Objects.isNull(surveyTitle)) {
                surveyTitle = ticketPageVO.getSurveyTitle();
            }
            ticketPageVO.setSurveyTitle(surveyTitle);

            // 当前处理人 ,2.3修改为如果跟进设置跟进人为层级类型，则显示角色下所有用户
            TicketInfo ticketInfo = TicketInfoConvert.entityToInfo(ticket);
            List<UserDTO> userDTOList = ticketService.getCurrentTicketUsers(ticketInfo);
            // 设置当前处理人
            if (CollectionUtils.isEmpty(userDTOList)) {
                ticketPageVO.setHandlerName(Collections.singletonList("系统"));
            } else {
                List<String> collect = userDTOList.stream().map(UserDTO::getName).collect(Collectors.toList());
                ticketPageVO.setHandlerName(collect);
            }

            // 新增工单名称 2.3版本添加
            ticketPageVO.setTicketName(ticket.getName());
            // 设置跟进逾期时间
            if (TicketStatusEnum.FOLLOWING.getIndex().equals(ticket.getStatus())) {
                if (Objects.nonNull(ticket.getFollowDeadline())) {
                    LocalDateTime localDateTime = LocalDateTime.ofInstant(ticket.getFollowDeadline().toInstant(), UTC_ZONE);
                    ticketPageVO.setFollowDeadline(Date.from(localDateTime.toInstant(BEIJING_ZONE)));
                }
            }

            // 工单配置信息
            TicketPageVO.AlertRule alertRule = alertCache.get(ticket.getTicketConfigId());
            if (Objects.nonNull(alertRule)) {
                ticketPageVO.setAlertRuleList(Collections.singletonList(alertRule));
            }

            ticketPageVOS.add(ticketPageVO);
        }

        pageDTO.setData(ticketPageVOS);
        return ServiceResult.success(pageDTO);
    }
}
    